package com.ld.zookeeper.api;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @author:ld
 * @create:2020-04-21 13:42
 * @description: zookeeper 原生API 修改节点数据
 */
public class ZookeeperSet {

    //连接对象
    private ZooKeeper zooKeeper;

    //连接地址
    private final String IP = "127.0.0.1:2181";

    private CountDownLatch countDownLatch = new CountDownLatch(1);

    /**
     * 开启连接
     */
    @Before
    public void befor() throws IOException, InterruptedException {
        //创建连接，因为是异步连接的，需要等待连接成功才能使用
        // arg1：连接地址
        // arg2：超时时间
        // arg3：自定义监视器
        zooKeeper = new ZooKeeper(IP, 5000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //连接成功
                if(Event.KeeperState.SyncConnected.equals(watchedEvent.getState())){
                    countDownLatch.countDown();
                    System.out.println("连接成功......");
                }else if(Event.KeeperState.Disconnected.equals(watchedEvent.getState())){
                    System.out.println("连接失败......");
                }else if(Event.KeeperState.AuthFailed.equals(watchedEvent.getState())){
                    System.out.println("用户认证失败......");
                }
            }
        });
        //等待连接成功
        countDownLatch.await();
    }

    /**
     * 关闭连接
     * @throws InterruptedException
     */
    @After
    public void after() throws InterruptedException {
        zooKeeper.close();
    }

    /**
     * 同步修改节点数据
     */
    @Test
    public void set1() throws KeeperException, InterruptedException {
        // arg1：节点路径
        // arg2：节点数据
        // arg3：数据版本号，-1：表示版本号不参与修改
        // return：返回节点状态对象
        Stat stat = zooKeeper.setData("/set/node1", "node1".getBytes(), 0);
        System.out.println("修改成功...... 版本号为：" + stat.getVersion());
    }

    /**
     * 异步修改节点数据
     */
    @Test
    public void set2(){

        //前三个参数上面已经介绍
        // arg4：回调接口
        // arg5：上下文对象
        zooKeeper.setData("/set/node2", "node2".getBytes(), -1, new AsyncCallback.StatCallback() {
            @Override
            public void processResult(int i, String s, Object o, Stat stat) {
                //修改结果，0表示修改成功
                System.out.println("修改结果：" + i);
                //节点路径
                System.out.println("节点路径：" + s);
                //上下文对象
                System.out.println("上下文对象：" + o);
                //节点状态对象
                System.out.println("版本号：" + stat.getVersion());
            }
        },"I am context");
    }

}
